import * as THREE from 'three'
import createApp from '../../core'

function createSpotLight (dom: HTMLElement) {
  const { camera, scene, renderer, gui } = createApp(dom)
  renderer.shadowMap.enabled = true
  renderer.shadowMap.type = THREE.PCFSoftShadowMap
  camera.position.set(-120, 80, 120)
  camera.lookAt(scene.position)

  const axes = new THREE.AxesHelper(100)
  scene.add(axes)

  const { ambientColor, ambientIntensity, color, intensity, distance, angle, penumbra, decay, x, y, z } = data
  const ambient = new THREE.AmbientLight(ambientColor, ambientIntensity)
  scene.add(ambient)

  const spotLight = new THREE.SpotLight(color, intensity, distance, angle, penumbra, decay)
  spotLight.position.set(x, y, z)
  spotLight.castShadow = true
  scene.add(spotLight)

  spotLight.shadow.mapSize.width = 512
  spotLight.shadow.mapSize.height = 512
  spotLight.shadow.camera.near = 0.5
  spotLight.shadow.camera.far = 500

  const helper = new THREE.SpotLightHelper(spotLight, 0xff0000)
  scene.add(helper)

  const shadowHelper = new THREE.CameraHelper(spotLight.shadow.camera)
  scene.add(shadowHelper)

  const planeGeometry = new THREE.PlaneGeometry(200, 200)
  const material = new THREE.MeshStandardMaterial({ color: 0xffffff })
  const plane = new THREE.Mesh(planeGeometry, material)
  plane.rotateX(-Math.PI / 2)
  plane.receiveShadow = true
  scene.add(plane)

  const boxGeometry = new THREE.BoxGeometry(30, 30, 30)
  const boxMaterial = new THREE.MeshStandardMaterial({ color: 0x0000ff })
  const box = new THREE.Mesh(boxGeometry, boxMaterial)
  box.castShadow = true
  box.position.set(0, 30, 0)
  scene.add(box)

  const folder1 = gui.addFolder('环境光参数')
  folder1.addColor(data, 'ambientColor').onChange(() => {
    ambient.color = new THREE.Color(data.ambientColor)
  })
  folder1.add(data, 'ambientIntensity', 0, 10).onChange(() => {
    ambient.intensity = data.ambientIntensity
  })

  const folder2 = gui.addFolder('点光源参数')
  folder2.addColor(data, 'color').onChange(() => {
    spotLight.color = new THREE.Color(data.color)
    helper.update()
  })
  folder2.add(data, 'intensity', 0, 10).onChange(() => {
    spotLight.intensity = data.intensity
    helper.update()
  })
  folder2.add(data, 'distance', 0, 500).onChange(() => {
    spotLight.distance = data.distance
    helper.update()
  })
  folder2.add(data, 'angle', 0, Math.PI * 2).onChange(() => {
    spotLight.angle = data.angle
    helper.update()
  })
  folder2.add(data, 'penumbra', 0, 10).onChange(() => {
    spotLight.penumbra = data.penumbra
    helper.update()
  })
  folder2.add(data, 'decay', 0, 10).onChange(() => {
    spotLight.decay = data.decay
    helper.update()
  })

  const folder3 = gui.addFolder('点光源位置')
  folder3.add(data, 'x', -200, 200).onChange(() => {
    spotLight.position.x = data.x
    helper.update()
  })
  folder3.add(data, 'y', -200, 200).onChange(() => {
    spotLight.position.y = data.y
    helper.update()
  })
  folder3.add(data, 'z', -200, 200).onChange(() => {
    spotLight.position.z = data.z
    helper.update()
  })
}

const data = {
  ambientColor: 0x454040,
  ambientIntensity: 1,
  color: 0xffffbb,
  intensity: 1,
  distance: 200,
  angle: Math.PI / 4,
  penumbra: 1,
  decay: 0,
  x: 0,
  y: 100,
  z: 0
}

export {
  createSpotLight
}
